/*
 * Created by SharpDevelop.
 * User: MyWife
 * Date: 11/1/2010
 * Time: 2:28 PM
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */

using System;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Collections;
using System.Threading;
using System.Data;
using System.Diagnostics;
using System.Windows.Forms;

namespace popLib.ExtensionClass
{
	/// <summary>
	/// Description of SocketClient.
	/// </summary>
	public class SocketClient
	{
		TcpClient tcpClient;
		NetworkStream networkStream;
		StreamReader streamReader;
		StreamWriter streamWriter;
		public string IP;
		public int Port;
		
		public delegate void ReceiveMessage(string message);
		public event ReceiveMessage ReceiveMessageEvent;
		
		public delegate void ConnectionStatusChanged(bool isConnected);
		public event ConnectionStatusChanged ConnectionStatusChangedEvent;
        public int ReconnectCounter = 0;
        public int MaxReconnectCounter = 10;
        public bool AutoReconnect = true;
        public bool WriteLog = true;
		
		public SocketClient( string ip, int port )
		{
			this.IP   = ip;
			this.Port = port;
		}
		
		Thread thread;
		public void Start(){
			thread = new Thread(Connect);
			thread.IsBackground = true;
			thread.Start();
		}
		
		public void Stop(){
			thread.Abort();
            tcpClient.Close();
		}
		
		private void Connect(){
			try
			{
				//init client socket
				tcpClient 			 = new TcpClient(IP, Port);
				networkStream 		 = tcpClient.GetStream();
				streamReader 		 = new StreamReader(networkStream);
				streamWriter 		 = new StreamWriter(networkStream);
				
				if( ConnectionStatusChangedEvent != null )
					ConnectionStatusChangedEvent(true);
				
	    		ProcessServer(null);
			}			
			catch(Exception ex)
			{					
				if(WriteLog)
                    FileLib.writeLog( FileLib.getFullPath( DateTime.Now.ToString("yyyyMMdd HHmm") + ".txt" ), ex, "PopLib.SocketClient.Connect" );
				Reconnect();
			}
		}
		
		private void Reconnect(){
            if (!AutoReconnect) return;

            ReconnectCounter++;
            if (ReconnectCounter > MaxReconnectCounter)
            {
                ReconnectCounter = 0;
                return;
            }

			Thread.SpinWait( 5000 );
			Connect();
		}
		
		#region Socket Handler Functions
		private void ProcessServer( object obj ){
			try
			{	
				while( true ){
					string message  = streamReader.ReadLine();
					if( ReceiveMessageEvent != null )
						ReceiveMessageEvent(message);
				}
			}			
			catch(Exception ex)
			{
                if (WriteLog) FileLib.writeLog(FileLib.getFullPath(DateTime.Now.ToString("yyyyMMdd HHmm") + ".txt"), ex, "PopLib.SocketClient.ProcessServer");
				
				if( ConnectionStatusChangedEvent != null )
					ConnectionStatusChangedEvent(false);
			}
			finally
			{
				tcpClient.Close();
			}			
			Reconnect();
		}
				
		public void SendMessage(string message){
			try{
				streamWriter.WriteLine(message);
				streamWriter.Flush();
			}catch(Exception ex){
                if (WriteLog) FileLib.writeLog(FileLib.getFullPath(DateTime.Now.ToString("yyyyMMdd HHmm") + ".txt"), ex, "PopLib.SocketClient.SendCommand");
			}
		}
		#endregion
	}
}
